/**
 * ==================== 封装的 http 请求工具​​ ====================
 */
import { isEmpty } from '@/utils/utils';
import { URLS } from './urls';


// 描述 header 的接口
interface RequestHeader {
    'Content-type'?: string;
    'Accept'?: string;
    'platform'?: string;
    'token'?: string;
    'access-key'?: string;
}

// ​​配置对象​，集中管理请求的默认配置
let u = {
    // 请求返回体模型
    httpModel: {
        resultCode: '0',
        message: '',
        data: [],

        errCode: '',
        errMsg: ''
    },

    // 请求方式
    GET: 'GET',
    POST: 'POST',
    PUT: 'PUT',
    DELETE: 'DELETE',

    // 请求状态 code
    statusCodeSuccess: 200, // 返回的 http 成功状态码
    codeSuccess: '0', // 接口请求成功 code
    codeFailure: '1', // 接口请求失败 code
    codeSessionIdTimeout: '1', // 用户 sessionId 过期 code

    // 错误信息
    defaultMessage: '您的网络信号不稳定，请重新加载或切换网络',

    // 初始化请求头，为空对象并断言为 RequestHeader 类型
    header: {} as RequestHeader,

    // 服务器地址
    host: (baseUrl: string = URLS.BASE_URL) => {
        return baseUrl;
    },

    // 拦截器，发请求前的拦截处理
    requestInterceptor(reqParams: any) {
        if (reqParams.url.includes('/login')) {
            delete u.header['token']; // 如果是登录接口，则不携带 token
        }
        return reqParams;
    },
}

// POST 请求
const httpPost = (reqParams: any) => {
    if (isEmpty(reqParams.params)) {
        reqParams.params = {};
    }
    request(reqParams, u.POST);
}

// GET 请求
const httpGet = (reqParams: any) => {
    if (isEmpty(reqParams.params)) {
        reqParams.params = {};
    }
    request(reqParams, u.GET);
}

// 发送请求
const request = (reqParams: any, requestType: string) => {
    let method = "";
    if (requestType == u.GET) {
        method = u.GET;
    } else if (requestType == u.POST) {
        method = u.POST;
    } else if (requestType == u.PUT) {
        method = u.PUT;
    } else if (requestType == u.DELETE) {
        method = u.DELETE;
    }

    updateHader();
    reqParams = u.requestInterceptor(setReqParams(reqParams));
    logRequestUrl(reqParams, method);

    // promise 发送请求
    promiseRequest(reqParams, method).then(
        // 成功
        (res) => {
            handleResponse(res, reqParams);
            // console.log("promise 发送请求成功");
            return res;
        },
        // 失败
        (err) => {
            handleResponse(err, reqParams);
            // console.log("promise 发送请求失败", err);
            if (reqParams.fail) {
                reqParams.fail(err);
            }
        }
    );
}

// 更新请求头
const updateHader = () => {
    // 当前平台
    let platform = uni.getDeviceInfo().platform;
    if (!isEmpty(platform)) {
        u.header['platform'] = platform;
    }

    // 在头部加token
    u.header['token'] = "";
    // let token = user.getToken();
    let token = "token";
    if (!isEmpty(token)) {
        u.header['token'] = token;
    }

    u.header['Content-type'] = 'application/x-www-form-urlencoded';
    u.header['Accept'] = 'application/json';
    u.header['access-key'] = "020313";

    // console.log("~~~ 未拦截前的请求头 header：", u.header);
}

// 配置公共参数
const setReqParams = (reqParams: any) => {
    // let openId = user.getOpenId();
    let openId = "1234567890";
    if (!isEmpty(openId)) {
        reqParams.params.openid = openId;
    }
    // let unionid = user.getUnionId();
    let unionid = "123";
    if (!isEmpty(unionid)) {
        reqParams.params.unionid = unionid;
    }
    // let globalId = user.getGlobalId();
    let globalId = "456";
    if (!isEmpty(globalId)) {
        reqParams.params.globalId = globalId;
    }
    // let talentNo = user.getTalentNo();
    let talentNo = "789";
    if (!isEmpty(talentNo)) {
        reqParams.params.talentNo = talentNo;
    }

    // reqParams.params.channel = 'mini_mrjob';
    // 仅在未传递 channel 时设置默认值
    if (isEmpty(reqParams.params.channel)) {
        reqParams.params.channel = 'mini_mrjob';
    }

    // 处理 value 为 undefined 的情况
    for (let key in reqParams.params) {
        let val = reqParams.params[key];
        if (!isEmpty(val)) {
            continue;
        }
        reqParams.params[key] = '';
    }

    return reqParams;
}

// 打印请求路径
const logRequestUrl = (reqParams: any, methor: string = '') => {
    let url = '\n------------------  HTTP START  ------------------\n\n';
    url += 'Url：' + u.host(reqParams.host) + reqParams.url + '\n';
    url += 'Method：' + methor + '\n';
    url += 'Header：' + JSON.stringify(u.header) + '\n';

    let params = '';
    let paramCount = objCount(reqParams.params);
    if (paramCount > 0) {
        // for...in 循环遍历对象的属性，不是最后一个才加上&
        let i = 0;
        for (let item in reqParams.params) {
            if (i != (paramCount - 1)) {
                params += item + "=" + reqParams.params[item] + '&';
            } else {
                params += item + "=" + reqParams.params[item];
            }
            i++;
        }
    }
    url += 'Params：' + params + '\n';
    url += '\n------------------  HTTP END  ------------------\n';
    // console.info(`%c ${url}`, 'color:#00FF7F; ');
}

// 计算请求参数 de 长度或属性数量
const objCount = (obj: any) => {
    let objType = typeof obj;
    if (objType == "string") {
        return obj.length;
    } else if (objType == "object") {
        let objLen = 0;
        for (let _i in obj) {
            objLen++;
        }
        return objLen;
    }
    return false;
}

// 实际发送请求的方法
const promiseRequest = (reqParams: any, method: any) => new Promise((resolve, reject) => {
    // 是否需要显示 loading
    let isLoading = false;
    if (!isEmpty(reqParams.loading)) {
        isLoading = true;
        uni.showNavigationBarLoading();
        uni.showLoading({
            title: reqParams.loading,
        })
    }

    let timeStart = Date.now();
    uni.request({
        url: `${u.host(reqParams.host)}${reqParams.url}`,
        data: reqParams.params,
        header: u.header,
        method: method,
    })
        .then(async (res: any) => {
            console.log(`\n=============  RESPONSE START  =============\n\n接口：${reqParams.url}\n耗时：${Date.now() - timeStart}ms\n返回的状态码：${res.statusCode}\n返回的数据：`, res, `\n----------------  RESPONSE END  ----------------\n\n`);

            // 关闭 PullDownRefresh 和 导航条加载动画、loading 
            uni.stopPullDownRefresh();
            if (isLoading) {
                uni.hideNavigationBarLoading();
                uni.hideLoading();
                uni.showToast({
                    title: "加载成功",
                    icon: "success"
                });
            }

            if (reqParams.complete) {
                reqParams.complete(res);
                // console.log("执行 reqParams.complete");
            }

            // if (res.data.result.resultCode == u.codeSuccess) {
            if (res.data.errCode == u.codeSuccess) {
                resolve(res)
                // console.log("执行 resolve(res)");
            } else {
                reject(res)
                // console.log("执行 reject(res)");
            }
        })
        .catch((err) => {
            // 关闭 loading
            if (isLoading) {
                uni.hideLoading();
            }
            reject(err);
            // console.log("执行 reject(err)");
        })
})

// 请求返回统一处理
const handleResponse = (result: any, reqParams: any) => {

    // 若网络请求返回码是 200
    if (result.statusCode == u.statusCodeSuccess) {
        // u.httpModel = result.data.result;
        u.httpModel = result.data;

        // code 为空
        if (isEmpty(u.httpModel.errCode)) {
            // if (!reqParams.isHideErr) {
            //     if (appInfo.getIsDev()) {
            //         showAction(u.defaultMessage);
            //     }
            // }
            return;
        }

        // 接口成功返回
        // if (u.httpModel.resultCode == u.codeSuccess) {
        if (u.httpModel.errCode == u.codeSuccess) {
            if (reqParams.success) {
                reqParams.success(u.httpModel)
            };
            return;
        }

        // 接口失败返回
        //  if (u.httpModel.resultCode == u.codeFailure) {
        if (u.httpModel.errCode == u.codeFailure) {
            if (!reqParams.isHideErr) {
                showAction(`${u.httpModel.message}`);
            }
            return;
        }

        // 用户 token 过期 code
        // if (u.httpModel.resultCode == u.codeSessionIdTimeout) {
        if (u.httpModel.errCode == u.codeSessionIdTimeout) {
            return;
        }

        // 其他的 code 码返回到页面自行处理
        if (isEmpty(u.httpModel.message)) {
            u.httpModel.message = u.defaultMessage;
        }

        // 
        if (!reqParams.isHideErr) {
            // if (appInfo.getIsDev()) {
            //     showAction(`${u.httpModel.message}`);
            // }
        }

        // 其他错误
        if (reqParams.fail) {
            showAction(`${u.httpModel.errMsg}`);
            // reqParams.fail(u.httpModel);
        }
    } else {
        let message = JSON.stringify(result);
        if (isEmpty(message) || message == '{}') {
            message = u.defaultMessage;
        }
        if (!reqParams.isHideErr) {
            // if (appInfo.getIsDev()) {
            //     showAction(`${message}`);
            // }
        }
    }
}

// 展示信息
const showAction = (message: string) => {
    if (isEmpty(message)) {
        return;
    }
    setTimeout(() => {
        uni.showToast({
            title: message,
            icon: 'none',
            duration: 3000
        });
    }, 200)
}

// promiseUpload
// httpPut
// httpDelete
// uploadFile

export default { httpPost, httpGet };
